#include "io_CConfigFile.h"
#include "io_CParser.h"

#include "..\mem\mem_manager.h"

#include <stdio.h>
#include <math.h>

CConfigFile::CConfigFile()
{
	m_numValues = 0;
	m_maxValues = 10;

	g_allocv(m_entries, TConfigEntry, m_maxValues);

	m_lastFile = NULL;
}

void CConfigFile::releaseData()
{
	for (int i=0;i<m_numValues;i++)
		g_free(m_entries[i].name);
	g_free(m_entries);

	m_numValues = 0;
	m_maxValues = 0;
}

CConfigFile::~CConfigFile()
{
	g_free(m_lastFile);
	releaseData();
}

int CConfigFile::readConfig(const char *file)
{
/*	g_free(m_lastFile);
	g_strdup(m_lastFile, file);

	CParser* parser = new CParser();

	if (parser->open(file) != CParser::PARSER_CONTINUE)
	{
		delete parser;
		return 0;
	}

	char token1[1024];
	char token2[1024];
	char token3[1024];

	while (!parser->eof())
	{
		parser->skipAll();
		parser->readToken(token1,1024);
		parser->skipAll();
		parser->readToken(token2,1024);
		parser->skipAll();
		parser->readToken(token3,1024);

		if (strlen(token1) && strlen(token2)&& strlen(token3))
		{
			if (!strcmp(token1, "setv"))
				setValue_asNumber(token2, strtod(token3, NULL));
			if (!strcmp(token1, "sets"))
				setValue_asString(token2, token3);
			if (!strcmp(token1, "setv"))
				setValue_asNumber(token2, strtod(token3, NULL));
		}
	}


	delete parser;*/
	return 1;
}

int CConfigFile::writeConfig(const char *file)
{
	g_free(m_lastFile);
	g_strdup(m_lastFile, file);

	FILE *f = fopen(file, "wt");
	if (!f)
		return 1;

	for (int i = 0; i < m_numValues; i++)
	{
		switch (m_entries[i].type)
		{
		case TYPE_NUMBER:
			if ((!(m_entries[i].flags & FLAG_HIDDEN))||(fabs(m_entries[i].val_current.asNumber-m_entries[i].val_default.asNumber)<0.001))
				fprintf(f, "setv %s\t\t%.5g\n", m_entries[i].name, m_entries[i].val_current.asNumber);
			break;
		case TYPE_STRING:
			if ((!(m_entries[i].flags & FLAG_HIDDEN))||stricmp(m_entries[i].val_current.asString, m_entries[i].val_default.asString))
				fprintf(f, "sets %s\t\t%\"%s\"\n", m_entries[i].name, m_entries[i].val_current.asString);
			break;
		case TYPE_KEY:
			if ((!(m_entries[i].flags & FLAG_HIDDEN))||(m_entries[i].val_current.asKey != m_entries[i].val_default.asKey))
				fprintf(f, "bind %s\t\t%d\n", m_entries[i].name, m_entries[i].val_current.asKey);
			break;
		}
	}

	fclose(f);

	return 0;
}

int CConfigFile::findKey(const char *key)
{
	for (int i = 0; i < m_numValues; i++)
		if (!strcmp(key, m_entries[i].name))
			return i;

	return -1;
}

CConfigFile::UValue CConfigFile::getValue(const char *name)
{
	int p = findKey(name);
	if (p >= 0)
		return m_entries[p].val_current;

	return m_entries[0].val_current;
}
int CConfigFile::createKey(const char* name, bool verify)
{
	int p;

	if (verify)
	{
		p = findKey(name);
		if (p>=0)
			return p;
	}

	if (m_numValues >= m_maxValues)
	{
		TConfigEntry *newEntries;
		int newMax = m_maxValues +(m_maxValues + 1)/2;

		g_allocv(newEntries, TConfigEntry, newMax);

		for (int i = 0; i < m_maxValues; i++)
			newEntries[i] = m_entries[i];

		g_free(m_entries);

		m_entries = newEntries;
		m_maxValues = newMax;
	}

	p = m_numValues++;
	g_strdup(m_entries[p].name, name);

	return p;
}

void CConfigFile::setValue_asNumber(const char *name, double value, int flags)
{
	int p = findKey(name);

	if (p<0)
	{	
		p=createKey(name,false);
		m_entries[p].val_default.asNumber = value;
		m_entries[p].flags = flags;
	}

	m_entries[p].val_current.asNumber = value;
	m_entries[p].type = TYPE_NUMBER;
}

void CConfigFile::setValue_asString(const char *name, const char* value, int flags)
{
	int p = findKey(name);

	if (p<0)
	{	
		p=createKey(name,false);
		g_strdup(m_entries[p].val_default.asString, value);
		m_entries[p].flags = flags;
	}

	g_strdup(m_entries[p].val_current.asString, value);
	m_entries[p].type = TYPE_STRING;
}

void CConfigFile::setValue_asKey(const char *name, char value, int flags)
{
	int p = findKey(name);

	if (p<0)
	{	
		p=createKey(name,false);
		m_entries[p].val_default.asKey = value;
		m_entries[p].flags = flags;
	}

	m_entries[p].val_current.asKey = value;
	m_entries[p].type = TYPE_KEY;
}

